iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
Modern Web

JS30 x 鐵人30 x MDN doc系列 第 1

[Day1] - Drum Kit(JS30 x 鐵人 30 x MDN)

  • 分享至 

  • xImage
  •  

今天我們來做一個可以演湊鼓聲的網頁

觀察 index-Start.html 可以發現作者已經創好各個按鍵容器及存放音檔的 Html Element,都擁有屬性"data-key"且兩兩成對,上網搜尋「鍵盤鍵碼值對照表」即可發現鍵盤的按鍵 K 即對應到鍵碼值 75

<div data-key="65" class="key">
  <kbd>A</kbd>
  <span class="sound">clap</span>
</div>
<audio data-key="65" src="sounds/clap.wav"></audio>

根據題目需求我們現在要的事就是當按下按鍵時,要透過 Javascriptd 去控制讓對應相同 data-key 值的<audio>tag 進行播放

  1. 使用EventTarget: addEventListener() method為這個視窗(Window)新增一個針對keydown event 按鍵按下的事件監聽器,當有按鍵按下都會執行函式 playSound
window.addEventListener("keydown", playSound);
  1. playSound 是一個專門為 event hanlder 寫的 function,e 代表事件發生時會自動傳入的物件,裡面記載著這個事件發生當下的各種詳細資訊(如下圖)

函式 playSound 中
(1)(2)使用.keycode 去Document: querySelector() method取得對應的<audio><div data-key="65" class="key">
(3)若沒有找到對應的按鈕及音檔節點則return不做任何事情,若有找到才做後續的步驟。
(4)將對應<audio>HTMLMediaElement: currentTime property先初始化為零。
(5)再使用HTMLMediaElement:play() method進行播放。
(6)最後將代表該按鍵的容器使用Element: classList property 的 add()method為其掛上"playing"這個動畫 CSS class。

function playSound(e) {
  const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);//(1)
  const button = document.querySelector(`.key[data-key="${e.keyCode}"]`);//(2)
  if (!audio || !button) return;//(3)
  audio.currentTime = 0;//(4)
  audio.play();//(5)
  button.classList.add("playing");//(6)
  1. 最後我們要針對移除"playing"這個動畫 CSS class 再寫一組事件監聽器

(1)這次我們改用Document: querySelectorAll() method先取得擁有"key"這個 className 的所有節點回傳為一個(NodeList 陣列)並把它存放於 keyList 變數中
(2)以 keyList 使用NodeList: forEach() method將每個符合的節點都新增一個針對transitionEnd EventCSS 轉變結束的事件監聽器,當 CSS 轉變結束時會執行函式 removeTransition
函式 removeTransition 中
(3)我們先判定事件的TransitionEvent: propertyName property若不是"transform"則return不做任何事情
(4)若有找到就從自己的 classList 中使用Element: classList remove()method把"playing"這個 class 移除

const keyList = document.querySelectorAll(".key"); // (1)
keyList.forEach((key) =>
  key.addEventListener("transitionend", removeTransition)
); //(2)

function removeTransition(e) {
  if (e.propertyName !== "transform") return; //(3)
  this.classList.remove("playing"); //(4)
}

👉Github Demo 頁面 👈

👉好想工作室15th鐵人賽看板👈

參考資料

  1. Javascript 30 官網
    https://javascript30.com/
  2. MDN 官網
    https://developer.mozilla.org/en-US/

下一篇
[Day2] - JS and CSS Clock(JS30 x 鐵人 30 x MDN)
系列文
JS30 x 鐵人30 x MDN doc30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
Jessie
iT邦新手 5 級 ‧ 2023-09-16 20:53:50

太讚了!/images/emoticon/emoticon31.gif

1
Vic
iT邦新手 3 級 ‧ 2023-09-18 21:11:55

有Github Demo頁面很棒 /images/emoticon/emoticon34.gif

我要留言

立即登入留言